#include <iostream>
#include "library2.h"
#include "sensorsystem.h"

using std::bad_alloc;

#define TO_SYSTEM(_SYSTEM_) (*(SensorSystem*)(_SYSTEM_))
#define TRY_CATCH_EXCEPTIONS(_TRY_CODE_)  \
		try{ \
				_TRY_CODE_ ; \
		}\
		catch (const bad_alloc&) { \
				return ALLOCATION_ERROR; \
		} \
		catch (const InvalidInputExcpetion&) { \
				return INVALID_INPUT; \
		} \
		catch (const FailureException& e3) { \
				return FAILURE; \
		}


bool isNull(void* ptr) {
		return (ptr == NULL);
}


void*       Init() {
		try {
				return new SensorSystem();
		}
		catch(...) {
				return NULL;
		}
}


StatusType AddSensor (void *DS, int id, Rational latitude, Rational temp)
{
	if (isNull(DS)) {
			return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS( TO_SYSTEM(DS).AddSensor(id,latitude,temp))
	return SUCCESS;
}

StatusType  RemoveSensor(void* DS, int id)
{
	if (isNull(DS)) {
			return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS(TO_SYSTEM(DS).RemoveSensor(id))
	return SUCCESS;
}


StatusType  ChangeSensorTemp(void* DS, int id, Rational temp)
{
	if (isNull(DS)) {
			return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS(TO_SYSTEM(DS).ChangeSensorTemp (id,temp))
	return SUCCESS;
}


StatusType  GetSensorTemp(void* DS, int id, Rational* temp)
{
	if (isNull(DS) || isNull(temp)) {
			return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS(*temp = TO_SYSTEM(DS).GetSensorTemp(id))
	return SUCCESS;
}

StatusType  AverageTemp(void* DS, Rational latitude1, Rational latitude2, Rational* temp)
{
	if (isNull(DS) || isNull(temp)) {
			return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS(*temp = TO_SYSTEM(DS).AverageTempInRange(latitude1,latitude2))
	return SUCCESS;
}

StatusType  MaxTemp(void* DS, Rational latitude1, Rational latitude2, Rational* temp)
{
	if (isNull(DS) || isNull(temp)) {
		return INVALID_INPUT;
	}
	TRY_CATCH_EXCEPTIONS(*temp = TO_SYSTEM(DS).MaxTempInRange(latitude1,latitude2))
	return SUCCESS;
}


void Quit(void** DS)
{
		if (DS==NULL)
		{
				return;
		}
		delete *((SensorSystem**)DS);
		*DS = NULL;
}
